package com.regan.erp.controller;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Duang;
import com.jfinal.core.Controller;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.regan.erp.aop.AuthPermission;
import com.regan.erp.aop.NotNullPara;
import com.regan.erp.aop.UserLoginInterceptor;
import com.regan.erp.aop.Verify4Para;
import com.regan.erp.controller.base.BaseController;
import com.regan.erp.exception.MyBaselogicException;
import com.regan.erp.model.*;
import com.regan.erp.service.UserService;
import com.regan.erp.util.*;

import java.io.File;
import java.sql.Time;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户管理
 *
 * @author zhangby
 * @action /user
 * @date 2018/9/11 下午3:14
 */
public class UserController extends BaseController {

    //用户管理service
    UserService userService = Duang.duang(UserService.class);

    /**
     * 获取用户详细信息
     *
     * @param id|当id为空时查询当前登录用户|String|非必填
     * @title 获取用户信息
     * @resqParam id|NULL|String|必填
     * @resqParam user_name|登录用户名|String|非必填
     * @resqParam password|密码|String|非必填
     * @resqParam nick_name|名称|String|非必填
     * @resqParam head_img|头像|String|非必填
     * @resqParam sex|'性别 0：其他，1：男，2：女'| int|非必填
     * @resqParam email|邮箱|String|非必填
     * @resqParam phone|手机号|String|非必填
     * @resqParam landline|电话|String|非必填
     * @resqParam country|国家|String|非必填
     * @resqParam province|省|String|非必填
     * @resqParam city|市|String|非必填
     * @resqParam county|县|String|非必填
     * @resqParam street|街道|String|非必填
     * @resqParam introduce|个人简介|String|非必填
     * @resqParam login_flag|'登录状态 ，0:正常，1:禁用'| int|非必填
     * @resqParam create_date|NULL|date|非必填
     * @resqParam update_date|NULL|date|非必填
     * @resqParam create_user_id|创建用户|String|非必填
     * @resqParam update_user_id|更新用户|String|非必填
     * @resqParam remarks|备注|String|非必填
     * @respBody {"code":"000","data":"...","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/13 下午8:17
     */
    public void getUserInfo() {
        String id = getPara("id");
        User user = null;
        if (StrKit.isBlank(id)) {
            user = UserUtil.getUser(getSession());
        } else {
            user = UserUtil.getUserById(id);
        }
        renderParseJson(ResultPoJo.create().result(user));
    }

    /**
     * 更新用户信息
     *
     * @param id|NULL|String|必填
     * @param user_name|登录用户名|String|非必填
     * @param nick_name|名称|String|非必填
     * @param email|邮箱|String|非必填
     * @param phone|手机号|String|非必填
     * @param country|国家|String|非必填
     * @param province|省|String|非必填
     * @param city|市|String|非必填
     * @param county|县|String|非必填
     * @param street|街道|String|非必填
     * @param introduce|个人简介|String|非必填
     * @title 更新用户
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/14 下午2:30
     */
    @Before(Tx.class)
    public void updateUserInfo() {
        //验证是否为系统管理员
        if (!User.isAdmin(getLoginUser().getId())
                && !getLoginUser().getId().equals(getPara("id"))) {
            throw new MyBaselogicException("800");
        }
        //更新用户
        save(getModel(User.class, "", true));
        renderText(ResultPoJo.create().toFastJson());
    }

    /**
     * 获取用户列表信息
     *
     * @param pageNum|分页页码（默认：1）|int|非必填
     * @param pageSize|分页条数              （默认：10）|int|非必填
     * @title 用户列表查询
     * @resqParam id|NULL|String|必填
     * @resqParam user_name|登录用户名|String|非必填
     * @resqParam nick_name|名称|String|非必填
     * @resqParam head_img|头像|String|非必填
     * @resqParam email|邮箱|String|非必填
     * @resqParam phone|手机号|String|非必填
     * @resqParam area_name|地区|String|非必填
     * @resqParam province|省|String|非必填
     * @resqParam create_date|NULL|date|非必填
     * @resqParam sex|'性别 0：其他，1：男，2：女'| int|非必填
     * @resqParam login_flag|'登录状态 ，0:正常，1:禁用'| int|非必填
     * @respBody {"code":"000","data":"...","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/16 上午10:38
     */
    public void getUserListData() {
        renderParseJson(ResultPoJo.create().result(userService.getUserListData(getParamDict(true))));
    }

    /**
     * 删除用户
     *
     * @param ids|用户id|list|必填
     * @title 用户删除
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/17 下午6:20
     */
    @NotNullPara({"ids"})
    @Before(Tx.class)
    public void delUser() {
        List<String> userName = Lists.newArrayList();
        String[] paraValues = getPara("ids", "").split(",");
        Lists.newArrayList(paraValues).forEach(id -> {
            //判断是否系统管理员
            if (User.isAdmin(id)) {
                userName.add(User.dao.findById(id).getName());
            } else {
                new User().setId(id).setDelFlag(Constants.YES_NO_1).update();
            }
        });
        if (!userName.isEmpty()) {
            throw new MyBaselogicException("999", "用户：" + ArrayUtil.join(userName.toArray(), ",") + " 删除失败，管理员不可删除");
        }
        renderJson(ResultPoJo.create());
    }

    /**
     * 导出excel
     *
     * @title 用户信息导出
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType get
     * @author zhangby
     * @date 2018/9/17 下午3:27
     */
    public void exportExcel4User() {
        //查询用户信息
        List<User> userList = User.dao.find(Db.getSqlPara("user.getUserListData"));
        //预处理
        FunctionUtils.execute(userList, User.preConsumer);
        File file = new File(PathKit.getRootClassPath() + "/tmp/用户信息.xlsx");
        renderFile(ExcelUtils.export(ExcelUtils.entity2Record(userList), User.EXCEL_KEY, file));
    }

    /**
     * 验证登录名是否重复
     *
     * @param user_name|用户名|String|必填
     * @param filter_id|过滤id|String|非必填
     * @title 用户名重复验证
     * @resqParam flag|状态：true 不重复 false 重复|boolean|必填
     * @respBody {"result": {"flag": false},"msg": "成功","code": "000"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/18 下午5:12
     */
    public void verifyUserName() {
        boolean flag = true;
        //过滤id
        String filter_id = getPara("filter_id", "");
        //获取用户名
        String user_name = getPara("user_name", "");
        //查询用户是否已存在，排除自己
        Record record = Db.findFirst("select id from t_user where user_name=? and del_flag=0", user_name);
        /** 验证是否重复 */
        if (ObjectUtil.isNotNull(record) && !record.getStr("id").equals(filter_id)) {
            flag = false;
        }
        renderJson(ResultPoJo.create().result(Kv.create().set("flag", flag)));
    }

    /**
     * 用户新增
     *
     * @param user_name|登录用户名|String|非必填
     * @param nick_name|名称|String|非必填
     * @param head_img|头像|String|非必填
     * @param email|邮箱|String|非必填
     * @param role|角色id,多个用逗号间隔|String|非必填
     * @param phone|手机号|String|非必填
     * @param sex|'性别 0：其他，1：男，2：女'| int|非必填
     * @title 新增用户
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/19 下午3:03
     */
    @Before(Tx.class)
    @NotNullPara({"user_name","email","role"})
    @AuthPermission({"syn:user:add","syn:user:edit"})
    public void saveUser() {
        User user = getModel(User.class, "", true);
        //设置默认密码
        user.setPassword(User.getDefaultPwd());
        //保存用户
        save(user);
        /** 添加角色 */
        String[] roles = getPara("role", "").split(",");
        //删除角色
        Db.delete("delete from t_user_role where user_id=?",user.getId());
        //循环添加角色
        for (String role : roles) {
            new UserRole().setUserId(user.getId()).setRoleId(Integer.parseInt(role)).save();
        }
        renderJson(ResultPoJo.create());
    }

    /**
     * 重置密码
     *
     * @param id|用户id|String|必填
     * @title 重置密码
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/19 下午5:08
     */
    @NotNullPara("id")
    @Before(Tx.class)
    public void resetPwd() {
        //验证是否为系统管理员
        if (!User.isAdmin(getLoginUser().getId())
                && !getLoginUser().getId().equals(getPara("id"))) {
            throw new MyBaselogicException("800");
        }
        new User().setId(getPara("id")).setPassword(User.getDefaultPwd4Md5()).update();
        renderJson(ResultPoJo.create().result(Kv.create().set("defaultPwd", User.getDefaultPwd())));
    }

    /**
     * 验证密码是否正确
     *
     * @param password|密码|String|必填
     * @title 密码验证
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/27 下午3:02
     */
    @NotNullPara("password")
    public void verifyPwd() {
        //验证密码是否正确
        if (!getLoginUser().getPassword().equals(md5(getPara("password")))) {
            throw new MyBaselogicException("104");
        }
        renderJson(ResultPoJo.create());
    }

    /**
     * 修改密码
     *
     * @param oldPwd|旧密码|String|必填
     * @param newPwd|新密码|String|必填
     * @title 修改密码
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/24 下午12:16
     */
    @NotNullPara({"oldPwd", "newPwd"})
    @Before(Tx.class)
    public void modifyPwd() {
        User loginUser = getLoginUser();
        //验证密码是否正确
        if (!loginUser.getPassword().equals(md5(getPara("oldPwd")))) {
            throw new MyBaselogicException("106");
        }
        //修改密码
        loginUser.setPassword(md5(getPara("newPwd"))).update();
        //退出登录
//        logout4Session();
        renderJson(ResultPoJo.create());
    }

    /**
     * 发送手机验证码
     *
     * @param phone|手机号|String|必填
     * @title 发送手机验证码
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/24 下午4:07
     */
    @NotNullPara("phone")
    public void sendPhoneAuthCode() {
        String phone = getPara("phone");
        //生成数字验证码
        renderJson(userService.sendPhoneAuthCode(phone));
    }

    /**
     * 验证手机短信验证码
     *
     * @param phone|手机号|String|必填
     * @param authCode|验证码|String|必填
     * @title 验证手机短信验证码
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/24 下午4:48
     */
    @NotNullPara({"phone", "authCode"})
    public void verifyPhoneAuthCode() {
        renderJson(userService.verifyPhoneAuthCode(getParamDict()));
    }

    /**
     * 修改手机号
     *
     * @param phone|手机号|String|必填
     * @param authCode|验证码|String|必填
     * @title 修改手机号
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/24 下午4:04
     */
    @NotNullPara({"phone", "authCode"})
    @Before(Tx.class)
    public void modifyPhone() {
        //验证手机验证码
        userService.verifyPhoneAuthCode(getParamDict());
        //修改手机号
        getLoginUser().setPhone(getPara("phone")).update();
        //清除redis
        UserUtil.clear(getLoginUser().getId());
        renderJson(ResultPoJo.create());
    }

    /**
     * 发送邮箱验证码
     *
     * @param email|邮箱|String|必填
     * @title 发送邮箱验证码
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/9/24 下午5:25
     */
    @NotNullPara("email")
    public void sendEmailAuthCode() {
        renderJson(userService.sendEmailAuthCode(getLoginUser(), getPara("email")));
    }

    /**
     * 邮箱验证码验证
     *
     * @param email|邮箱|String|必填
     * @param authCode|验证码|String|必填
     * @title 验证邮箱验证码
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/10/10 下午5:00
     */
    @NotNullPara({"email", "authCode"})
    public void verifyEmailAuthCode() {
        renderJson(userService.verifyEmailAuthCode(getParamDict()));
    }

    /**
     * 修改邮箱
     *
     * @param email|邮箱|String|必填
     * @param authCode|验证码|String|必填
     * @title 修改邮箱
     * @resqParam code|状态码|String|必填
     * @resqParam data|数据|object|非必填
     * @resqParam msg|消息信息|String|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/10/11 上午10:35
     */
    @NotNullPara({"email", "authCode"})
    @Before(Tx.class)
    public void modifyEmail() {
        //验证验证码是否正确
        userService.verifyEmailAuthCode(getParamDict());
        //更新邮箱
        getLoginUser().setEmail(getPara("email")).update();
        //刷新缓存
        UserUtil.clear(getLoginUser().getId());
        renderJson(ResultPoJo.create());
    }

    /**
     * 获取用户授权菜单
     * @title 获取用户授权菜单
     * @param type|'类型：1 目录 ，2 菜单 ， 3 按钮' ，默认：1|string|非必填
     * @resqParam name|菜单名称|String|必填
     * @resqParam path|路径|String|必填
     * @resqParam icon|图标|String|非必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/10/23 下午5:07
     */
    public void getUserMenu() {
        renderParseJson(ResultPoJo.create().result(getUserRoleMenu(getPara("type","1"))));
    }

    /**
     *
     * 验证授权菜单按钮权限
     * @title 功能菜单权限验证
     * @param permission|授权码|String|必填
     * @resqParam authFlag|true：有权限，false：没有权限|boolean|必填
     * @respBody {"code":"000","data":"","msg":"success"}
     * @requestType post
     * @author zhangby
     * @date 2018/10/23 上午11:04
     */
    @NotNullPara("permission")
    public void verifyAuth() {
        renderParseJson(ResultPoJo.create().result(Kv.create().set("authFlag",verifyAuth(getPara("permission")))));
    }
}
